﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using RemoteControlModel;
using System.Runtime.Serialization.Formatters.Binary;
using Intorise.Common;
using Intorise.Net;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;

namespace MuBot
{
    public partial class MainWindow
    {
        private static TcpClient client = null;
        private static NetTools net = new NetTools();

        public void InitRemoteControl()
        {
            Register();
        }

        private void Register()
        {
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    try
                    {
                        client = new TcpClient("127.0.0.1", 520);
                        var stream = client.GetStream();
                        var message = new RegisterMessage { ClientName = AppDomain.CurrentDomain.BaseDirectory };
                        var data = message.Serialize();
                        stream.Write(data, 0, data.Length);
                    }
                    catch (Exception ex)
                    {
                        ConsoleBLL.WriteLineError(ex.Message);
                    }
                    if (client != null && client.Connected)
                    {
                        ConsoleBLL.WriteLineInfo("管理服务器连接成功！");
                        break;
                    }
                    else
                    {
                        ConsoleBLL.WriteLineWaring("无法连接管理服务器，30秒后再次尝试！");
                        Thread.Sleep(1000 * 30);
                    }
                }

                ProcessMessage();
            });
        }

        private void ProcessMessage()
        {
            ConsoleBLL.WriteLineInfo("开始等待管理服务器消息...");
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    try
                    {
                        var msg = ReadMessage(client.GetStream());
                        if (msg == null)
                        {
                            continue;
                        }
                        ConsoleBLL.WriteLineInfo("收到管理服务器消息：" + msg.MessageType);
                        switch (msg.MessageType)
                        {
                            case MessageTypeEnum.Reboot:
                                Reboot();
                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        ConsoleBLL.WriteLineError(ex.Message);
                    }
                    if (!client.Connected)
                    {
                        ConsoleBLL.WriteLineWaring("与管理服务器的连接已断开，重新连接...");
                        Register(); break;
                    }
                }
            });
        }

        private static RemoteControlModel.Message ReadMessage(NetworkStream stream)
        {
            BinaryFormatter formater = new BinaryFormatter();
            byte[] buffer = new byte[102400];

            int length = stream.Read(buffer, 0, 4);//读取4个字节为接下来的数据包的长度
            if (length < 4)
            {
                return null;
            }

            var packgetLength = net.GetHostInt32(buffer, 0);
            if (packgetLength > buffer.Length)
            {
                buffer = new byte[packgetLength];
            }
            length = stream.Read(buffer, 0, packgetLength);
            if (length != packgetLength)
            {
                ConsoleBLL.WriteLineError("读取数据异常，length!=packgetLength"); return null;
            }

            RemoteControlModel.Message message = null;

            try
            {
                using (MemoryStream memory = new MemoryStream(buffer, 0, packgetLength))
                {
                    message = (RemoteControlModel.Message)formater.Deserialize(memory);
                }
            }
            catch (Exception ex)
            {
                ConsoleBLL.WriteLineError(ex.Message);
            }

            if (message == null)
            {
                ConsoleBLL.WriteLineError("反序列化Message失败！");
            }
            return message;
        }

        private static void Reboot()
        {
            ConsoleBLL.WriteLineWaring("重新启动程序...");
            Process p = new Process();
            p.StartInfo = new ProcessStartInfo(Application.ExecutablePath);
            p.StartInfo.WorkingDirectory = Application.StartupPath;
            //p.StartInfo.Arguments = "/a ";
            p.Start();
            Application.Exit();
        }
    }
}
